﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace NetWorm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        delegate void AsynUpdateUI(AccessData step);
        private void button1_Click(object sender, EventArgs e)
        {
            // int taskCount = 100; //任务量为10000
            List<WebSiteData> webSiteData = new List<WebSiteData>();
            try
            {
                using (StreamReader sr = new StreamReader(Application.StartupPath + "\\website.txt", Encoding.Default))
                {

                    String line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        string _line = line.ToString();
                        if (!string.IsNullOrEmpty(_line))
                        {
                            string[] s = line.Split(',');
                            webSiteData.Add(new WebSiteData() { Num = Convert.ToInt32(s[0].Trim()), WebSite = s[1].Trim() });
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("配置文件异常,请检查 文件名 website.txt 格式 1208,http://ok.sanjia.com 一行一个网址 ");
                return;
            }

            DataWrite dataWrite = new DataWrite();//实例化一个写入数据的类
            dataWrite.UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
            dataWrite.TaskCallBack += Accomplish;//绑定完成任务要调用的委托

            Thread thread = new Thread(new ParameterizedThreadStart(dataWrite.Write));
            thread.IsBackground = true;
            thread.Start(webSiteData);
        }

        //更新UI
        private void UpdataUIStatus(AccessData step)
        {
            if (InvokeRequired)
            {
                this.Invoke(new AsynUpdateUI(delegate (AccessData s)
                {
                    var item = new ListViewItem(new string[] { step.Website, step.Status, step.Error, step.Length, step.TimeLong, DateTime.Now.ToString() });
                    item.UseItemStyleForSubItems = false;
                    item.SubItems[1].ForeColor = Color.Green;
                    if (step.Status == "异常")
                        item.SubItems[1].ForeColor = Color.Red;
                    else if (step.Status == "警告")
                        item.SubItems[1].ForeColor = Color.Yellow;
                    listView1.Items.Insert(0, item);
                }), step);
            }
            else
            {
                //this.pgbWrite.Value += step;
                //this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
            }
        }

        //完成任务时需要调用
        private void Accomplish(List<AccessData> results)
        {

            //发送邮寄
            if (emailSet.Checked)
            {
                if (results != null)
                {
                    if (sendEx.Checked)
                    {
                        results = results.Where(d => d.Status != "正常").ToList();
                    }
                    if (results.Count > 0)
                    {
                        string bodyInfo = "";
                        foreach (var item in results)
                        {
                            bodyInfo += "【" + item.Status + "】" + item.Website + "<br/>";
                        }
                        try
                        {
                            //smtp.163.com
                            string senderServerIp = this.textBox_serverIp.Text;
                            //smtp.gmail.com
                            //string senderServerIp = "74.125.127.109";
                            //smtp.qq.com
                            //string senderServerIp = "58.251.149.147";
                            //string senderServerIp = "smtp.sina.com";
                            string toMailAddress = this.textBox_to.Text;
                            string fromMailAddress = this.textBox_from.Text;
                            string subjectInfo = "检测报告";
                            // string bodyInfo = "Hello Eric, This is my first testing e_mail";
                            string mailUsername = this.textBox_username.Text;
                            string mailPassword = this.textBox_password.Text; //发送邮箱的密码（）
                            string mailPort = this.textBox_port.Text;
                            // string attachPath = "E:\\123123.txt; E:\\haha.pdf";

                            MyEmail email = new MyEmail(senderServerIp, toMailAddress, fromMailAddress, subjectInfo, bodyInfo, mailUsername, mailPassword, mailPort, false, false);
                            // email.AddAttachments(attachPath);
                            email.Send();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show("邮件发送失败,原因：" + ex.Message);

                            return;
                        }
                    }
                }

            }

            //还可以进行其他的一些完任务完成之后的逻辑处理
            MessageBox.Show("任务完成");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (this.listView1.Items.Count < 1)
            {
                MessageBox.Show("请先运行获取列表再来此处操作");
                return;
            }
            textBox1.Text = "";
            foreach (ListViewItem item in this.listView1.Items)
            {
                textBox1.Text += item.SubItems[3].Text + ',' + item.SubItems[0].Text + "\r\n";
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            this.listView1.Items.Clear();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                FileStream fs = new FileStream(Application.StartupPath + "\\website.txt", FileMode.Create);
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                sw.Write(this.textBox1.Text);
                //清空缓冲区
                sw.Flush();
                //关闭流
                sw.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("失败：" + ex.Message);
            }
            MessageBox.Show("设置成功");
        }

        private void button5_Click(object sender, EventArgs e)
        {
            textBox1.Text = "";
            try
            {
                using (StreamReader sr = new StreamReader(Application.StartupPath + "\\website.txt", Encoding.Default))
                {
                    String line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        string _line = line.ToString();
                        if (!string.IsNullOrEmpty(_line))
                        {
                            textBox1.Text += _line + "\r\n";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("配置文件异常,请检查 文件名 website.txt 格式 1208,http://ok.sanjia.com 一行一个网址 ");
                return;
            }
        }


        public static System.Timers.Timer aTimer;
        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (timeSet.Checked)
            {
                aTimer = new System.Timers.Timer();
                aTimer.Elapsed += new System.Timers.ElapsedEventHandler(button1_Click);
                int timeNum = Convert.ToInt32(this.timeNum.Value);
                if (timeNum < 1)
                {
                    timeNum = 1;
                }
                aTimer.Interval = timeNum * 60 * 1000;
                aTimer.AutoReset = true;
                aTimer.Enabled = true;
            }
            else
            {
                aTimer.Stop();
            }
        }



        private void Form1_SizeChanged_1(object sender, EventArgs e)
        {
            //当窗体最小化时，隐藏到系统托盘中
            if (WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon1.Visible = true;
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
        }
    }
}

public class DataWrite
{
    public delegate void UpdateUI(AccessData step);//声明一个更新主线程的委托
    public UpdateUI UpdateUIDelegate;

    public delegate void AccomplishTask(List<AccessData> results);//声明一个在完成任务时通知主线程的委托
    public AccomplishTask TaskCallBack;

    public void Write(object obj)
    {
        List<WebSiteData> webSiteData = obj as List<WebSiteData>;
        //结果
        List<AccessData> results = new List<AccessData>();
        foreach (var item in webSiteData)
        {
            var data = new AccessData() { Status = "正常", Length = "0" };
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            try
            {
                data.Website = item.WebSite.Trim();
                string content = Get(data.Website);
                stopwatch.Stop();
                data.TimeLong = stopwatch.ElapsedMilliseconds.ToString();
                if (item.Num != content.Length)
                {
                    data.Status = "警告";
                    data.Error = "存在挂马风险";
                }
                data.Length = content.Length.ToString();

            }
            catch (Exception ex)
            {
                data.Status = "异常";
                data.Error = ex.Message;
                stopwatch.Stop();
                data.TimeLong = stopwatch.ElapsedMilliseconds.ToString();
            }
            results.Add(data);

            UpdateUIDelegate(data);
        }
        //任务完成时通知主线程作出相应的处理
        TaskCallBack(results);
        //  writeIO.Close();
    }
    // private static string USER_AGENT = string.Format("WXPaySDK/{3} ({0}) .net/{1} {2}", Environment.OSVersion, Environment.Version, WxPayConfig.GetConfig().GetMchID(), typeof(HttpService).Assembly.GetName().Version);
    /// <summary>
    /// 处理http GET请求，返回数据
    /// </summary>
    /// <param name="url">请求的url地址</param>
    /// <returns>http GET成功后返回的数据，失败抛WebException异常</returns>
    public static string Get(string url)
    {
        System.GC.Collect();
        string result = "";

        HttpWebRequest request = null;
        HttpWebResponse response = null;

        //请求url以获取数据
        try
        {
            //设置最大连接数
            ServicePointManager.DefaultConnectionLimit = 200;
            //设置https验证方式
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                //  ServicePointManager.ServerCertificateValidationCallback =
                //         new RemoteCertificateValidationCallback(true);
            }

            /***************************************************************
            * 下面设置HttpWebRequest的相关属性
            * ************************************************************/
            request = (HttpWebRequest)WebRequest.Create(url);
            //   request.UserAgent = USER_AGENT;
            request.Method = "GET";

            //获取服务器返回
            response = (HttpWebResponse)request.GetResponse();

            //获取HTTP返回数据
            StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            result = sr.ReadToEnd().Trim();
            sr.Close();
        }
        catch (System.Threading.ThreadAbortException e)
        {
            System.Threading.Thread.ResetAbort();
        }
        catch (WebException e)
        {
            throw new WebException(e.ToString());
        }
        catch (Exception e)
        {
            throw new Exception(e.ToString());
        }
        finally
        {
            //关闭连接和流
            if (response != null)
            {
                response.Close();
            }
            if (request != null)
            {
                request.Abort();
            }
        }
        return result;
    }


}

public class AccessData
{
    public string Website { get; set; }
    public string Status { get; set; }
    public string Error { get; set; }

    public string Length { get; set; }

    public string TimeLong { get; set; }
    public string CreateTime { get; set; }

}

public class WebSiteData
{
    public int Num { get; set; }
    public string WebSite { get; set; }
}
